using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public abstract class Board : MonoBehaviour
{
	#region public

	[Serializable]
    public  struct Move
    {
        public int x1;
        public int y1;
        public int x2;
        public int y2;
        public int playerID;

        public Move(int x1, int y1, int x2, int y2, int playerID)
        {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.playerID = playerID;
        }

		public override string ToString()
		{
			return string.Format("[Move]\nx: {0} y: {1} => x: {2} y: {3}\n By player: {4}", x1, y1, x2, y2, playerID);
		}
    }

	[Serializable]
    public struct Action
    {
        public enum Type
        {
            Add = 0,
            Remove,
            Swap,
            ComboBegin,
            ComboEnd
        }

        public Type type;
        public List<Point> from;
        public List<Point> to;
        public List<List<Point>> lines;
        public List<int> gemTypes;
        public int playerID;

        public Action(Type type, int playerID = -1)
        {
            this.type = type;
            this.playerID = playerID;
            from = new List<Point>();
            to = new List<Point>();
            lines = new List<List<Point>>();
            gemTypes = new List<int>();
        }
    }

    public delegate void ActionChainDelegate(Queue<Action> actionChain);

    public event ActionChainDelegate onMainActionChain;
    public event ActionChainDelegate onNewActionChain;

    public void InvokeOnMainActionChain(Queue<Action> actionChain)
    {
        if (onMainActionChain != null)
            onMainActionChain(actionChain);
    }

    public void InvokeOnNewActionChain(Queue<Action> actionChain)
    {
        if (onNewActionChain != null)
            onNewActionChain(actionChain);
    }

	//Board display initialization
	public abstract void Init (GameManager gm, int width, int height);
	// Main function that handles player input and make board correspond in manner appropriate to game mode
	public abstract void MakeSwap (int x1, int y1, int x2, int y2, int playerID = 0);

	#endregion
	#region protected

    protected GameManager m_GameManager;
	protected IBoardDisplay m_BoardDisplay;

	#endregion
}